---
title: Embedding the dashboard
sidebar_position: 20
---

Convex provides a hosted dashboard that is embeddable via iframe. Embedding the
dashboard is useful for developers building AI app generators, like
[Convex Chef](https://chef.convex.dev).

You can embed the Convex dashboard by adding an `<iframe>` to
https://dashboard-embedded.convex.dev. Normally, the embedded dashboard requires
the user to enter credentials to use it, but you may skip the login step by
providing deployment credentials via a
[`postMessage`](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage)
to the iframe.

When using `postMessage`, there may be a delay until the credentials are
received. The default login page will be shown until credentials are received,
so we recommend adding a delay before displaying the rendered iframe to avoid
flashing a login screen.

<Admonition
  type="caution"
  title="This will share the credentials of the deployment client-side"
>
  When using `postMessage` to authenticate with the embedded dashboard, the
  deployment key will be shared with the end-user. This means that the user gets
  full control of the deployment. Do this only when sharing credentials with the
  user is safe, such as with an [OAuth
  Application](/platform-apis/oauth-applications) (for Convex deployments that
  are in the Convex account of the end user), or deploy keys [created with the
  Management API](/management-api/create-deploy-key) (if the Convex deployment
  is in a Convex account that the end user doesn’t control).
</Admonition>

Required information for `postMessage`:

- `deploymentUrl`: The deployment cloud URL. Returned when creating the project
  with the [Create project API](/management-api/create-project)
- `deploymentName`: The readable identifier for the deployment. Returned when
  creating the project with the
  [Create project API](/management-api/create-project).
- `adminKey`: A deploy key scoped to the specified `deploymentName`. Can be
  retrieved with the [Create deploy key API](/management-api/create-deploy-key).

Optional configuration:

- `visiblePages`: An array of page keys to show in the sidebar. If not provided,
  all pages are shown. If an empty array is provided, the sidebar will be
  hidden. Available page keys: `"health"`, `"data"`, `"functions"`, `"files"`,
  `"schedules"`, `"logs"`, `"history"`, `"settings"`. Please note that this only
  changes the user interface on the client side, and does not strictly prevent
  the user from accessing the functionality exposed by the pages.

Here's an example of the Convex dashboard embedded in a React application:

```tsx
import { useEffect, useRef } from "react";

export function Dashboard({
  deploymentUrl,
  deploymentName,
  deployKey,
  visiblePages,
}: {
  deploymentUrl: string;
  deploymentName: string;
  deployKey: string;
  visiblePages?: string[];
}) {
  const iframeRef = useRef<HTMLIFrameElement>(null);

  useEffect(() => {
    const handleMessage = (event: MessageEvent) => {
      // We first wait for the iframe to send a dashboard-credentials-request message.
      // This makes sure that we don't send the credentials until the iframe is ready.
      if (event.data?.type !== "dashboard-credentials-request") {
        return;
      }
      iframeRef.current?.contentWindow?.postMessage(
        {
          type: "dashboard-credentials",
          adminKey: deployKey,
          deploymentUrl,
          deploymentName,
          // Optional: specify which pages to show
          visiblePages,
        },
        "*",
      );
    };

    window.addEventListener("message", handleMessage);
    return () => window.removeEventListener("message", handleMessage);
  }, [deploymentUrl, adminKey, deploymentName, visiblePages]);

  return (
    <iframe
      ref={iframeRef}
      // You can also default on other pages, for instance /functions, /files or /logs
      src="https://dashboard-embedded.convex.dev/data"
      allow="clipboard-write"
    />
  );
}
```
